home *** CD-ROM | disk | FTP | other *** search
Wrap
/* AquaShade hack MacHack 2001 Nicholas Riley Avi Drissman with thanks to: Mike Ferris Chris Nebel Ed Wynne Shawn Platkus Known funkiness: Sometimes, a collapsed window will not get the proper deactivated appearance. No idea why. Often, the window widget glyphs will stay around after the mouse leaves their proximity. Probably due to the fact that we do window attribute slamming. */ #include "main.h" DEFINE_ONE_SHOT_HANDLER_GETTER(MinEventHandler) DEFINE_ONE_SHOT_HANDLER_GETTER(TicTacEventHandler) DEFINE_ONE_SHOT_HANDLER_GETTER(CloseEventHandler) void InitAquaShade(void) { static EventLoopTimerUPP eventLoopTimer; if (!eventLoopTimer) eventLoopTimer = NewEventLoopTimerUPP(EventTimer); InstallEventLoopTimer(GetMainEventLoop(), kEventDurationSecond, kEventDurationSecond, eventLoopTimer, nil, nil); PatchEveryWindow(); } void PatchEveryWindow(void) // Ford every stream... { WindowRef window; window = GetWindowList(); while (window) { PatchWindow(window); window = MacGetNextWindow(window); } } void PatchWindow(WindowRef window) { EventTypeSpec minList[] = {{kEventClassWindow, kEventWindowCollapse}, {kEventClassWindow, kEventWindowCollapseAll}}; EventTypeSpec ttList = {kEventClassWindow, kEventWindowToolbarSwitchMode}; EventTypeSpec closeList[] = {{kEventClassWindow, kEventWindowClose}, {kEventClassWindow, kEventWindowCloseAll}}; InstallWindowEventHandler(window, GetMinEventHandlerUPP(), 2, minList, nil, nil); InstallWindowEventHandler(window, GetTicTacEventHandlerUPP(), 1, &ttList, nil, nil); InstallWindowEventHandler(window, GetCloseEventHandlerUPP(), 2, closeList, nil, nil); } // XXX this is broken OSStatus pascal CloseEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) { WindowRef window; fprintf(stderr, "I'm closing...\n"); switch (GetEventKind (inEvent)) { case kEventWindowClose: // Get the window if (GetEventParameter(inEvent, kEventParamDirectObject, typeWindowRef, nil, sizeof (window), nil, &window)) return CallNextEventHandler(inHandlerCallRef, inEvent); //? WindowShade(window, false); break; case kEventWindowCloseAll: window = GetWindowList(); while (window) { WindowShade(window, false); window = MacGetNextWindow(window); } } return CallNextEventHandler(inHandlerCallRef, inEvent); } OSStatus pascal MinEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) { WindowRef window; if (GetCurrentKeyModifiers() & (controlKey | rightControlKeyBit)) return CallNextEventHandler(inHandlerCallRef, inEvent); // Get the window if (GetEventParameter(inEvent, kEventParamDirectObject, typeWindowRef, nil, sizeof (window), nil, &window)) return CallNextEventHandler(inHandlerCallRef, inEvent); //? switch (GetEventKind(inEvent)) { case kEventWindowCollapse: WindowShade(window, !(GetCurrentKeyModifiers() & (shiftKey | rightShiftKeyBit))); break; case kEventWindowCollapseAll: window = GetWindowList(); while (window) { WindowShade(window, !(GetCurrentKeyModifiers() & (shiftKey | rightShiftKeyBit))); window = MacGetNextWindow(window); } break; } return noErr; } OSStatus pascal TicTacEventHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) { WindowRef window; Boolean collapsed = false; // Get the window GetEventParameter(inEvent, kEventParamDirectObject, typeWindowRef, nil, sizeof (window), nil, &window); // Is it collapsed? GetWindowProperty(window, 'AShd', 'Coll', sizeof(collapsed), nil, &collapsed); // if property isn't there, then we've never touched the window, and it's expanded... if (collapsed) return noErr; // ignore else return CallNextEventHandler(inHandlerCallRef, inEvent); } void pascal EventTimer(EventLoopTimerRef inTimer, void *inUserData) { PatchEveryWindow(); } void WindowShade(WindowRef window, Boolean slide) { Boolean collapsed = false; struct WindowInfo winfo; // Should we be expanding or contracting? if (GetWindowProperty(window, 'AShd', 'Coll', sizeof(collapsed), nil, &collapsed)) collapsed = false; PlaySound(); if (collapsed) { Rect newRect; if (slide) { GetWindowBounds(window, kWindowGlobalPortRgn, &newRect); if (newRect.top != 0) newRect.top -= kWindowTitleBarHeight; } // we need to restore it GetWindowProperty(window, 'AShd', 'Winf', sizeof(winfo), nil, &winfo); if (slide) { Point offset; offset.h = newRect.left - winfo.oldSize.left; offset.v = newRect.top - winfo.oldSize.top; winfo.oldSize.top += offset.v; winfo.oldSize.bottom += offset.v; winfo.oldSize.left += offset.h; winfo.oldSize.right += offset.h; TransitionWindow(window, kWindowSlideTransitionEffect, kWindowResizeTransitionAction, &winfo.oldSize); } else { SizeWindow(window, winfo.oldSize.right - winfo.oldSize.left, winfo.oldSize.bottom - winfo.oldSize.top - ((newRect.top != 0) ? kWindowTitleBarHeight : 0), true); } ChangeWindowAttributes(window, kWindowNoAttributes, 0xFFFFFFFF); ChangeWindowAttributes(window, winfo.oldAttrs, kWindowNoAttributes); collapsed = false; SetWindowProperty(window, 'AShd', 'Coll', sizeof(collapsed), &collapsed); } else // must collapse it { if (slide) { GetWindowBounds(window, kWindowGlobalPortRgn, &winfo.oldSize); if (winfo.oldSize.top != 0) winfo.oldSize.top -= kWindowTitleBarHeight; } else { GetWindowBounds(window, kWindowContentRgn, &winfo.oldSize); if (winfo.oldSize.top != 0) winfo.oldSize.bottom += kWindowTitleBarHeight; } GetWindowAttributes(window, &winfo.oldAttrs); SetWindowProperty(window, 'AShd', 'Winf', sizeof(winfo), &winfo); // take away inconvenient "features" ChangeWindowAttributes(window, kWindowNoShadowAttribute, kWindowFullZoomAttribute | kWindowResizableAttribute); if (GetCurrentKeyModifiers() & alphaLock) { GrafPtr oldPort; Rect rect = {0x8000, 0x8000, 0x7fff, 0x7fff}; Pattern blackPat; GetPort(&oldPort); SetPortWindowPort(window); ForeColor(blackColor); FillRect(&rect, GetQDGlobalsBlack(&blackPat)); SetPort(oldPort); } // collapse if (slide) { winfo.oldSize.bottom = winfo.oldSize.top + 1; if (winfo.oldSize.top != 0) winfo.oldSize.bottom += kWindowTitleBarHeight; TransitionWindow(window, kWindowSlideTransitionEffect, kWindowResizeTransitionAction, &winfo.oldSize); } else { SizeWindow(window, winfo.oldSize.right - winfo.oldSize.left, 1, true); } collapsed = true; SetWindowProperty(window, 'AShd', 'Coll', sizeof(collapsed), &collapsed); } } void PlaySound() { SysBeep(100); /* FSRef fref; OSErr err = FSPathMakeRef("/Users/avidriss/AquaShade/open", &fref, NULL); Movie movie; FSSpec fsp; short refnum; if (err != noErr) ExitToShell(); err = FSGetCatalogInfo(&fref, 0, NULL, NULL, &fsp, NULL); if (err != noErr) ExitToShell(); /* OpenMovieFile(&fsp, &refnum, fsRdPerm); NewMovieFromFile(&movie, refnum, NULL, (StringPtr)NULL, newMovieActive, NULL); if (refnum != 0) CloseMovieFile(refnum); // play the movie once thru StartMovie(movie); while (!IsMovieDone(movie)) MoviesTask(movie, 0); DisposeMovie(movie); err = FSpOpenDF( &fsp, fsRdPerm, &refnum ); if ( err != noErr ) ExitToShell(); err = SndStartFilePlay( nil, refnum, 0, 40960, nil, nil, nil, false ); if ( err != noErr ) ExitToShell(); */ }